using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Sage.Http.Factory;
using Sage.Http.Handlers;
using Sage.Http.Options;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Sage.Http.Extensions
{
    /// <summary>
    /// 依赖注入扩展方法
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 添加HTTP请求管理器工厂及其依赖服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddHttpRequestManagerFactory(this IServiceCollection services)
        {
            // 添加HttpClient工厂
            services.AddHttpClient();
            
            // 注册工厂
            services.AddSingleton<IHttpRequestManagerFactory, HttpRequestManagerFactory>();

            return services;
        }

        /// <summary>
        /// 添加HTTP请求管理器工厂并配置全局JSON序列化选项
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="jsonSerializerOptions">JSON序列化选项</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddHttpRequestManagerFactory(
            this IServiceCollection services,
            JsonSerializerOptions jsonSerializerOptions)
        {
            ArgumentNullException.ThrowIfNull(jsonSerializerOptions);

            // 添加HttpClient工厂
            services.AddHttpClient();
            
            // 配置全局JSON选项
            JsonSerializerOptionsFactory.SetGlobalOptions(jsonSerializerOptions);

            // 注册工厂
            services.AddSingleton<IHttpRequestManagerFactory, HttpRequestManagerFactory>();

            return services;
        }

        /// <summary>
        /// 添加HTTP请求管理器工厂并配置全局JSON序列化上下文（AOT友好）
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="jsonSerializerContext">JSON序列化上下文</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddHttpRequestManagerFactory(
            this IServiceCollection services,
            JsonSerializerContext jsonSerializerContext)
        {
            ArgumentNullException.ThrowIfNull(jsonSerializerContext);

            // 添加HttpClient工厂
            services.AddHttpClient();
            
            // 配置全局JSON上下文
            JsonSerializerOptionsFactory.SetGlobalContext(jsonSerializerContext);

            // 注册工厂
            services.AddSingleton<IHttpRequestManagerFactory, HttpRequestManagerFactory>();

            return services;
        }

        /// <summary>
        /// 添加HTTP请求管理器工厂并同时配置JSON选项和上下文
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="jsonSerializerOptions">JSON序列化选项</param>
        /// <param name="jsonSerializerContext">JSON序列化上下文</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddHttpRequestManagerFactory(
            this IServiceCollection services,
            JsonSerializerOptions jsonSerializerOptions,
            JsonSerializerContext jsonSerializerContext)
        {
            ArgumentNullException.ThrowIfNull(jsonSerializerOptions);
            ArgumentNullException.ThrowIfNull(jsonSerializerContext);

            // 添加HttpClient工厂
            services.AddHttpClient();
            
            // 配置全局JSON选项和上下文
            JsonSerializerOptionsFactory.SetGlobalOptions(jsonSerializerOptions);
            JsonSerializerOptionsFactory.SetGlobalContext(jsonSerializerContext);

            // 注册工厂
            services.AddSingleton<IHttpRequestManagerFactory, HttpRequestManagerFactory>();

            return services;
        }

        /// <summary>
        /// 添加类型化的HTTP请求管理器
        /// </summary>
        /// <typeparam name="TClient">客户端类型</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="name">客户端名称</param>
        /// <param name="configureClient">配置客户端的委托</param>
        /// <param name="retryOptions">重试选项</param>
        /// <param name="circuitBreakerOptions">熔断器选项</param>
        /// <param name="defaultTimeout">默认超时时间</param>
        /// <param name="loggingOptions">日志选项</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTypedHttpRequestManager<TClient>(
            this IServiceCollection services,
            string name,
            Action<HttpClient>? configureClient = null,
            RetryOptions? retryOptions = null,
            CircuitBreakerOptions? circuitBreakerOptions = null,
            TimeSpan? defaultTimeout = null,
            LoggingOptions? loggingOptions = null) where TClient : class
        {
            // 确保已注册HttpRequestManagerFactory
            services.TryAddSingleton<IHttpRequestManagerFactory, HttpRequestManagerFactory>();

            // 添加带弹性的HTTP客户端
            var builder = services.AddHttpClientWithResilience(
                name,
                configureClient,
                retryOptions,
                circuitBreakerOptions,
                defaultTimeout,
                loggingOptions);

            // 注册类型化客户端
            services.AddTransient<TClient>(provider =>
            {
                var factory = provider.GetRequiredService<IHttpRequestManagerFactory>();
                var manager = factory.GetHttpRequestManager(name);
                return ActivatorUtilities.CreateInstance<TClient>(provider, manager);
            });

            return services;
        }
        /// <summary>
        /// 添加带有高级功能的HTTP客户端
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="name">客户端名称</param>
        /// <param name="configureClient">客户端配置操作</param>
        /// <param name="retryOptions">重试策略配置</param>
        /// <param name="circuitBreakerOptions">熔断器配置</param>
        /// <param name="defaultTimeout">默认请求超时</param>
        /// <param name="loggingOptions">日志记录配置</param>
        /// <returns>HTTP客户端构建器</returns>
        public static IHttpClientBuilder AddHttpClientWithResilience(
            this IServiceCollection services,
            string name,
            Action<HttpClient>? configureClient = null,
            RetryOptions? retryOptions = null,
            CircuitBreakerOptions? circuitBreakerOptions = null,
            TimeSpan? defaultTimeout = null,
            LoggingOptions? loggingOptions = null)
        {
            var timeout = defaultTimeout ?? TimeSpan.FromSeconds(120);
            var retry = retryOptions ?? new RetryOptions();
            var circuitBreaker = circuitBreakerOptions ?? new CircuitBreakerOptions();
            var logging = loggingOptions ?? new LoggingOptions();

            var builder = services.AddHttpClient(name, client =>
            {
                configureClient?.Invoke(client);
                if (defaultTimeout.HasValue)
                {
                    client.Timeout = defaultTimeout.Value;
                }
            });
            
            // 添加日志处理器
            if (logging.LogRequests || logging.LogResponses)
            {
                builder.AddHttpMessageHandler(provider =>
                {
                    var logger = provider.GetRequiredService<ILoggerFactory>()
                        .CreateLogger<LoggingHandler>();
                    return new LoggingHandler(logger, logging);
                });
            }
            
            // 添加超时处理器
            if (timeout != Timeout.InfiniteTimeSpan)
            {
                builder.AddHttpMessageHandler(() => new TimeoutHandler(timeout));
            }
            
            // 添加重试处理器
            if (retry.Enabled)
            {
                builder.AddHttpMessageHandler(provider =>
                {
                    var logger = provider.GetRequiredService<ILoggerFactory>()
                        .CreateLogger($"HttpClient.{name}.RetryHandler");
                    return new RetryHandler(retry, logger);
                });
            }
            
            // 添加熔断处理器
            if (circuitBreaker.Enabled)
            {
                builder.AddHttpMessageHandler(provider =>
                {
                    var logger = provider.GetRequiredService<ILoggerFactory>()
                        .CreateLogger($"HttpClient.{name}.CircuitBreakerHandler");
                    return new CircuitBreakerHandler(circuitBreaker, logger);
                });
            }

            return builder;
        }

        /// <summary>
        /// 添加带有高级功能和JSON配置的HTTP客户端
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="name">客户端名称</param>
        /// <param name="configureClient">客户端配置操作</param>
        /// <param name="jsonSerializerOptions">JSON序列化选项</param>
        /// <param name="retryOptions">重试策略配置</param>
        /// <param name="circuitBreakerOptions">熔断器配置</param>
        /// <param name="defaultTimeout">默认请求超时</param>
        /// <param name="loggingOptions">日志记录配置</param>
        /// <returns>HTTP客户端构建器</returns>
        public static IHttpClientBuilder AddHttpClientWithResilience(
            this IServiceCollection services,
            string name,
            Action<HttpClient> configureClient,
            JsonSerializerOptions jsonSerializerOptions,
            RetryOptions? retryOptions = null,
            CircuitBreakerOptions? circuitBreakerOptions = null,
            TimeSpan? defaultTimeout = null,
            LoggingOptions? loggingOptions = null)
        {
            ArgumentNullException.ThrowIfNull(jsonSerializerOptions);

            // 配置全局JSON选项
            JsonSerializerOptionsFactory.SetGlobalOptions(jsonSerializerOptions);

            // 调用原始方法
            return AddHttpClientWithResilience(services, name, configureClient, retryOptions, circuitBreakerOptions, defaultTimeout, loggingOptions);
        }

        /// <summary>
        /// 添加带有高级功能和JSON上下文的HTTP客户端（AOT友好）
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="name">客户端名称</param>
        /// <param name="configureClient">客户端配置操作</param>
        /// <param name="jsonSerializerContext">JSON序列化上下文</param>
        /// <param name="retryOptions">重试策略配置</param>
        /// <param name="circuitBreakerOptions">熔断器配置</param>
        /// <param name="defaultTimeout">默认请求超时</param>
        /// <param name="loggingOptions">日志记录配置</param>
        /// <returns>HTTP客户端构建器</returns>
        public static IHttpClientBuilder AddHttpClientWithResilience(
            this IServiceCollection services,
            string name,
            Action<HttpClient> configureClient,
            JsonSerializerContext jsonSerializerContext,
            RetryOptions? retryOptions = null,
            CircuitBreakerOptions? circuitBreakerOptions = null,
            TimeSpan? defaultTimeout = null,
            LoggingOptions? loggingOptions = null)
        {
            ArgumentNullException.ThrowIfNull(jsonSerializerContext);

            // 配置全局JSON上下文
            JsonSerializerOptionsFactory.SetGlobalContext(jsonSerializerContext);

            // 调用原始方法
            return AddHttpClientWithResilience(services, name, configureClient, retryOptions, circuitBreakerOptions, defaultTimeout, loggingOptions);
        }

        /// <summary>
        /// 添加带有高级功能和完整JSON配置的HTTP客户端
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="name">客户端名称</param>
        /// <param name="configureClient">客户端配置操作</param>
        /// <param name="jsonSerializerOptions">JSON序列化选项</param>
        /// <param name="jsonSerializerContext">JSON序列化上下文</param>
        /// <param name="retryOptions">重试策略配置</param>
        /// <param name="circuitBreakerOptions">熔断器配置</param>
        /// <param name="defaultTimeout">默认请求超时</param>
        /// <param name="loggingOptions">日志记录配置</param>
        /// <returns>HTTP客户端构建器</returns>
        public static IHttpClientBuilder AddHttpClientWithResilience(
            this IServiceCollection services,
            string name,
            Action<HttpClient> configureClient,
            JsonSerializerOptions jsonSerializerOptions,
            JsonSerializerContext jsonSerializerContext,
            RetryOptions? retryOptions = null,
            CircuitBreakerOptions? circuitBreakerOptions = null,
            TimeSpan? defaultTimeout = null,
            LoggingOptions? loggingOptions = null)
        {
            ArgumentNullException.ThrowIfNull(jsonSerializerOptions);
            ArgumentNullException.ThrowIfNull(jsonSerializerContext);

            // 配置全局JSON选项和上下文
            JsonSerializerOptionsFactory.SetGlobalOptions(jsonSerializerOptions);
            JsonSerializerOptionsFactory.SetGlobalContext(jsonSerializerContext);

            // 调用原始方法
            return AddHttpClientWithResilience(services, name, configureClient, retryOptions, circuitBreakerOptions, defaultTimeout, loggingOptions);
        }
    }
}